package sanmubird.club.mock.controller;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;

import java.io.File;
import java.io.FileInputStream;
import java.net.URI;
import java.util.Map;

/**
 * @author sam
 * @date 2019/12/6 11:06
 * @description 功能描述
 */
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) // Spring Boot启动的时候采用一个随机的端口，有助于在测试环境中避免冲突
@AutoConfigureMockMvc  // 这个注解的功效 初始化好 一个 mockMvc 对象
public class SimpleMockControllerDemoTest2 {

	@Autowired
	MockMvc mockMvc;

	@Before
	public void setUp() throws Exception {
	}


	@After
	public void tearDown() throws Exception {
	}

	@Test
	public void simpleGetDemo() throws Exception {
		/**
		 * 1、mockMvc.perform执行一个请求。
		 * 2、MockMvcRequestBuilders.get("XXX")构造一个请求。
		 * 3、ResultActions.param添加请求传值
		 * 4、ResultActions.accept(MediaType.TEXT_HTML_VALUE))设置返回类型
		 * 5、ResultActions.andExpect添加执行完成后的断言。
		 * 6、ResultActions.andDo添加一个结果处理器，表示要对结果做点什么事情
		 *   比如此处使用MockMvcResultHandlers.print()输出整个响应结果信息。
		 * 5、ResultActions.andReturn表示执行完成后返回相应的结果。
		 *
		 * 整个测试过程如下：
		 * 1、准备测试环境
		 * 2、通过MockMvc执行请求
		 * 3、添加验证断言
		 * 4、添加结果处理器
		 * 5、得到MvcResult进行自定义断言/进行下一步的异步请求
		 * 6、卸载测试环境
		 */

		MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.get("/mock/simpleGetDemo")
				.param("name", "wmq")
				.accept(MediaType.TEXT_HTML_VALUE))
				// .andExpect(MockMvcResultMatchers.status().isOk())             //等同于Assert.assertEquals(200,status);
				// .andExpect(MockMvcResultMatchers.content().string("hello wmq"))    //等同于 Assert.assertEquals("hello wmq",content);
				.andDo(MockMvcResultHandlers.print())
				.andReturn();
		int status = mvcResult.getResponse().getStatus();                 //得到返回代码
		String content = mvcResult.getResponse().getContentAsString();    //得到返回结果

		Assert.assertEquals(200, status);                        //断言，判断返回代码是否正确
		Assert.assertEquals("hello wmq", content);            //断言，判断返回的值是否正确
	}

	@Test
	public void simplePathVariableGetDemo() throws Exception {
		MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.get("/mock/simplePathVariableGetDemo/hello")
				.param("name", "wmq")
				.accept(MediaType.TEXT_HTML_VALUE))
				.andDo(MockMvcResultHandlers.print())
				.andReturn();
		int status = mvcResult.getResponse().getStatus();                 //得到返回代码
		String content = mvcResult.getResponse().getContentAsString();    //得到返回结果

		Assert.assertEquals(200, status);                        //断言，判断返回代码是否正确
		Assert.assertEquals("hello wmq", content);            //断言，判断返回的值是否正确
	}

	@Test
	public void simpleJsonPostDemo() throws Exception {
		Map map = Maps.newHashMap();
		map.put("name", "wmq");

		MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post("/mock/simpleJsonPostDemo")
				.contentType(MediaType.APPLICATION_JSON)
				.content(JSONObject.toJSONString(map))
				.accept(MediaType.TEXT_HTML_VALUE))
				.andDo(MockMvcResultHandlers.print())
				.andReturn();

		int status = mvcResult.getResponse().getStatus();                 //得到返回代码
		String content = mvcResult.getResponse().getContentAsString();    //得到返回结果

		Assert.assertEquals(200, status);                        //断言，判断返回代码是否正确
		Assert.assertEquals("{\"name\":\"wmq\"}", content);            //断言，判断返回的值是否正确
	}

	@Test
	public void simpleFileUploadDemo() throws Exception {
		final URI uri = SimpleMockControllerDemoTest2.class.getClassLoader().getResource("io").toURI();
		final FileInputStream fileInputStream = new FileInputStream(new File(new File(uri), "demo.csv"));
		MockMultipartFile mockMultipartFile = new MockMultipartFile("demo.csv", "demo.csv", null, fileInputStream);
		MvcResult mvcResult = mockMvc
				.perform(
						MockMvcRequestBuilders
								.multipart("/mock/simpleFileUploadDemo")
								.file(mockMultipartFile)
				)
				.andExpect(MockMvcResultMatchers.status().isOk())
				.andExpect(MockMvcResultMatchers.content().string("demo.csv"))
				.andDo(MockMvcResultHandlers.print()).andReturn();

	}
}